package com.atjinggu.jinggumail.oauth.controller;

import com.alibaba.fastjson.TypeReference;
import com.atjinggu.jinggumail.common.constant.AuthConstant;
import com.atjinggu.jinggumail.common.enums.BizCodeEnum;
import com.atjinggu.jinggumail.common.utils.R;
import com.atjinggu.jinggumail.common.vo.MemberResponseVo;
import com.atjinggu.jinggumail.oauth.feign.MemberFeignService;
import com.atjinggu.jinggumail.oauth.feign.ThirdPartFeignService;
import com.atjinggu.jinggumail.oauth.vo.UserLoginVo;
import com.atjinggu.jinggumail.oauth.vo.UserRegistVo;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import javax.servlet.http.HttpSession;
import javax.validation.Valid;
import java.time.Duration;
import java.time.Instant;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * @author jingming
 * @Type LoginController.java
 * @Desc
 * @date 2021/2/23 10:32
 */
@Controller
@RequestMapping("/")
public class LoginController {

    @Autowired
    ThirdPartFeignService thirdPartFeignService;

    @Autowired
    StringRedisTemplate redisTemplate;

    @Autowired
    MemberFeignService memberFeignService;

    @GetMapping("/sendcode")
    @ResponseBody
    public R sendCode(@RequestParam("phone") String phone) {
        //1.验证码防刷

        //2. 验证码再次校验 存到redis中
        String redisCode = redisTemplate.opsForValue().get(AuthConstant.SMS_CODE_CACHE_PREFIX + phone);
        if(StringUtils.isNotEmpty(redisCode)){
            String time = redisCode.split("_")[1];
            Instant parse = Instant.parse(time);
            if(Duration.between(parse,Instant.now().plusMillis(TimeUnit.HOURS.toMillis(8))).toMillis() < 60 * 1000){
                return R.error(BizCodeEnum.SMSCODE_Times_EXCEPTION.getCode(),BizCodeEnum.SMSCODE_Times_EXCEPTION.getMessage());
            }
        }

        String code = UUID.randomUUID().toString().substring(0, 5);
       R r =  thirdPartFeignService.sendSmsCode(phone, code);
       if(r.getCode() == 0){
           //redis中，过期时间为5分钟
          redisTemplate.opsForValue().set(AuthConstant.SMS_CODE_CACHE_PREFIX+phone,code+"_"+ Instant.now().plusMillis(TimeUnit.HOURS.toMillis(8)).toString(),Duration.ofMinutes(5));
       }
        return R.ok();
    }


    @PostMapping("/regist")
    public String regist(@Valid UserRegistVo vo, BindingResult result, RedirectAttributes  ra){
        if(result.hasErrors()){
            Map<String, String> errors = result.getFieldErrors().stream().collect(Collectors.toMap(FieldError::getField, FieldError::getDefaultMessage,(n,o) -> o));
            ra.addFlashAttribute("errors",errors); //只需要取一次，就没了
            //return "register";
            //防止表单重复提交，使用重定向方式
            return "redirect:http://oauth.jinggumail.com/register.html";
        }
        String code = redisTemplate.opsForValue().get(AuthConstant.SMS_CODE_CACHE_PREFIX + vo.getPhone());

        if(StringUtils.isEmpty(code)){
            Map<String, String> errors = new HashMap();
            errors.put("code","验证码错误");
            ra.addFlashAttribute("errors",errors); //只需要取一次，就没了
            //return "register";
            //防止表单重复提交，使用重定向方式
            return "redirect:http://oauth.jinggumail.com/register.html";
        }

        if(!StringUtils.equals(code.split("_")[0],vo.getCode())){
            Map<String, String> errors = new HashMap();
            errors.put("code","验证码错误");
            ra.addFlashAttribute("errors",errors); //只需要取一次，就没了
            //return "register";
            //防止表单重复提交，使用重定向方式
            return "redirect:http://oauth.jinggumail.com/register.html";
        }

        //对比成功，删除验证码
        redisTemplate.delete(AuthConstant.SMS_CODE_CACHE_PREFIX + vo.getPhone());

        R regist = memberFeignService.regist(vo);
        if(regist.getCode() != 0){
            Map<String, String> errors = new HashMap();
            errors.put("msg",regist.getData("msg",new TypeReference<String>(){}));
            ra.addFlashAttribute("errors",errors);
            return "redirect:http://oauth.jinggumail.com/register.html";
        }


        return "redirect:http://oauth.jinggumail.com/login.html";
    }


    @PostMapping("/login")
    public String login(UserLoginVo vo,RedirectAttributes  ra, HttpSession session){
        R login = memberFeignService.login(vo);
        if(login.getCode() != 0){
            Map<String, String> errors = new HashMap();
            errors.put("msg",login.getData("msg",new TypeReference<String>(){}));
            ra.addFlashAttribute("errors",errors);
            return  "redirect:http://oauth.jinggumail.com/login.html";
        }
        MemberResponseVo data = login.getData("data", new TypeReference<MemberResponseVo>() {
        });
        session.setAttribute(AuthConstant.LOGIN_USER,data);
        return "redirect:http://jinggumail.com";
    }

    @GetMapping("/login.html")
    public String loginPage(HttpSession session){
        Object attribute = session.getAttribute(AuthConstant.LOGIN_USER);
        if(attribute != null){
            return "redirect:http://jinggumail.com";
        }else {
            return  "login";
        }

    }


    public static void main(String[] args) {
        Instant parse = Instant.parse("2021-02-23T16:46:41.656Z");
        System.out.println(Duration.between(parse,Instant.now().plusMillis(TimeUnit.HOURS.toMillis(8))).toMillis());

        System.out.println(Instant.now().plusMillis(TimeUnit.HOURS.toMillis(8)));

    }
}